package front

import (
	"fmt"
	"net/http"
	"reflect"
	"shop/pkg/app"
	"strconv"

	"github.com/gin-gonic/gin"
)

type ArrayController struct {
}

func (e *ArrayController) Arraystest(c *gin.Context) {
	var appG = app.Gin{C: c}

	var arr1 [5]int
	var arr2 = [7]int{1, 2, 3, 4, 6, 99, 101}
	//fmt.Println("arr1", arr1)
	//fmt.Println("arr2", arr2)

	// 练习二
	arr3 := [3]string{"go", "php", "java"}

	arr4 := [...]string{"python", "c++", "ruby"}
	arr5 := [...]int{10, 20, 30, 40, 50}

	//循环数组
	for i := 0; i < len(arr5); i++ {
		arr1[i%5] += arr5[i]
	}

	for key, val := range arr4 {
		fmt.Println("key:%d , val: %d\n", key, val)
	}

	for _, value := range arr3 {
		fmt.Println("value:%d", value)
	}

	//修改数组
	scores := [...]float64{1.1, 2.2, 3.3, 4.4, 5.5}
	var sum float64
	for _, score := range scores {
		sum += score
	}
	avg := sum / float64(len(scores))
	fmt.Println("avg:", avg)
	fmt.Println("scores before:", scores)
	fmt.Println("sum:", sum)

	//数组值修改
	newarr6 := c.DefaultQuery("newarr6", "20")
	newarr6int, err := strconv.Atoi(newarr6)
	if err != nil {
		appG.Response(http.StatusBadRequest, "newarr6参数格式错误", nil)
	}
	arr6 := [...]int{10, 20, 30, 40, 50}
	arr6[2] = newarr6int

	//增加元素
	arr7 := []int{1, 2, 3, 4, 5}
	arr7 = append(arr7, newarr6int)
	arr7 = append(arr7, 110, 120, 130)

	// 向客户端返回 JSON 响应
	c.JSON(200, gin.H{
		"success": true,
		"message": "数组数据获取成功",
		"data": gin.H{
			"arr1": arr1,
			"arr2": arr2,
			"arr3": arr3,
			"arr4": arr4,
			"arr5": arr5,
			"arr6": arr6,
			"arr7": arr7,
		},
	})
}

func (e *ArrayController) SliceInfo(c *gin.Context) {
	//var appG = app.Gin{C: c}

	slices1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	fmt.Println("slices1:%d", slices1, "len:", len(slices1), "cap:", cap(slices1))

	slices2 := "切片测试"
	s1 := []rune(slices2)
	s1[0] = '我'

	fmt.Println("slices2:%d", string(s1), "len:", len(s1), "cap:", cap(s1))

	// 方法1: 通过数组创建切片
	ar1 := [5]int{1, 2, 3, 4, 5}
	sli1 := ar1[1:3] // 包含索引1到2的元素 [2, 3]
	fmt.Println("cli1:%d", sli1, "len:", len(sli1), "cap:", cap(sli1))

	//方法2: 使用make函数创建切片

	slic2 := make([]int, 4, 5) //长度为4，容量为5
	slic2[0] = 10
	slic2[1] = 20
	slic2[2] = 30
	slic2[3] = 40
	//slic2[4] = 50 //会报错，索引越界
	slic2 = append(slic2, 50) //可以通过append添加元素
	slic2 = append(slic2, 60) //可以通过append添加元素，超过容量会自动扩容

	fmt.Println("slic2:%d", slic2, "len:", len(slic2), "cap:", cap(slic2))

	// 方法三

	slice3 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}

	sl3 := slice3[1:6] //包含索引2到2的元素 [3]
	sl4 := slice3[:4]  //从索引0到3的元素 [1,2,3,4]
	fmt.Println("sl3 before:%d", sl3, "len:", len(sl3), "cap:", cap(sl3))
	fmt.Println("slice3:%d", slice3, "len:", len(slice3), "cap:", cap(slice3))

	slic4 := make([]string, 3, 10)
	fmt.Println("slic4:%d", slic4, "len:", len(slic4), "cap:", cap(slic4))

	//数组与切片对比
	arrx := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} //是子数组

	aliasx := arrx[1:6]
	aliasx = append(aliasx, 100, 111)
	fmt.Println("aliasx:%d", aliasx, "len:", len(aliasx), "cap:", cap(aliasx))

	clicex := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} //是子切片
	aliasx1 := append(clicex, 100, 111)
	fmt.Println("aliasx:%d", aliasx1, "len:", len(aliasx1), "cap:", cap(aliasx1))

	//切片string
	slistring := []string{"hello", "world", "go"}
	slistring = append(slistring, "golang", "php")
	str1 := append(slistring, "python")

	str1[1] = "Node"

	for _, v := range str1 {
		fmt.Println("str1:%d", v)
	}

	//5. 切片的动态操作

	var sliceOne []int
	sliceOne = append(sliceOne, 10)
	sliceOne = append(sliceOne, 20)
	sliceOne = append(sliceOne, 40, 50)

	sliceTwo := []int{99, 100}
	clices := append(sliceOne, sliceTwo...)

	//复制切片
	src := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	dst := make([]int, len(src))

	fmt.Printf("src 类型: %T\n", src) // 输出: []int
	fmt.Printf("dst 类型: %T\n", dst) // 输出: []int

	// 使用反射验证
	fmt.Printf("src 是切片: %v\n", reflect.TypeOf(src).Kind() == reflect.Slice)
	fmt.Printf("dst 是切片: %v\n", reflect.TypeOf(dst).Kind() == reflect.Slice)

	// 输出详细信息
	fmt.Printf("src: %v, len: %d, cap: %d\n", src, len(src), cap(src))
	fmt.Printf("dst: %v, len: %d, cap: %d\n", dst, len(dst), cap(dst))

	n := copy(dst, src)
	fmt.Println("n:", n)

	//插入元素 到切片
	addSlice()

	//删除切片
	deleteSlice()

	//多维切片
	multDime()

	//循环数组内容
	qiepian()

	c.JSON(200, gin.H{
		"success": true,
		"message": "切片数据获取成功",
		"data": gin.H{
			//"slices1": slices1,
			//"slic2":   slic2,
			"sl3":       sl3,
			"sl4":       sl4,
			"slistring": slistring,
			"str1":      str1,
			"clices":    clices,
			"n":         n,
		},
	})
}

func addSlice() {
	slices := []string{"php", "go", "python", "java"}

	slices = append(slices, "mhz", "ly")

	mhz := make([]string, 2)
	mhz[0] = "mhz1"
	mhz[1] = "ly1"

	slices = append(slices, mhz...)

	// 在索引2处插入元素3
	// 在索引2处插入元素"nodel"
	index := 2
	toInsert := []string{"nodel"}
	slices = append(slices[:index], append(toInsert, slices[index:]...)...)

	fmt.Println("slices:", slices)
}

func deleteSlice() {
	slices := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	// 删除索引为2的元素（值为3）
	index := 2
	slices = append(slices[:index], slices[index+1:]...)
	fmt.Println("slices:", slices)
	// 删除第一个元素
	slices = slices[1:]
	fmt.Println("slices:", slices)

	// 删除最后一个元素
	slices = slices[:len(slices)-1]
	fmt.Println("slices:", slices)

}

// 多维切片
func multDime() {
	matrix := make([][]int, 3)
	for i := range matrix {
		matrix[i] = make([]int, 3)
		for j := range matrix[i] {
			matrix[i][j] = i + j
		}
	}
	fmt.Println(matrix)
	for i := range matrix {
		fmt.Println(matrix[i])
	}
}

// 切片
func qiepian() {
	newslc := []int{100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000}
	//fmt.Println(newslc[1:5])

	for i, v := range newslc {
		fmt.Printf("Index %d: %d\n", i, v)
	}
}
